package com.cmc.cloud.cmclink.doc.controller.admin.so;

import cn.hutool.core.collection.ListUtil;
import com.cmc.cloud.cmclink.common.logging.LogSetting;
import com.cmc.cloud.cmclink.doc.api.document.emums.ContentChangeStatusEnum;
import com.cmc.cloud.cmclink.doc.api.document.emums.SoContentStatusEnum;
import com.cmc.cloud.cmclink.doc.api.document.req.soamendapplyvo.SoAmendApplyUpdateReqVO;
import com.cmc.cloud.cmclink.doc.constants.UrlConstants;
import com.cmc.cloud.cmclink.doc.rpcservice.IbsMgmtService;
import com.cmc.cloud.cmclink.doc.service.impl.so.SoQueryServiceImpl;
import com.cmc.cloud.cmclink.doc.service.so.BizSoService;
import com.cmc.cloud.cmclink.doc.vo.CodCheckReqVO;
import com.cmc.cloud.cmclink.doc.vo.sovo.sovo.*;
import com.cmc.cloud.cmclink.doc.vo.sovo.sovslvoyvo.SoVslvoyScheduleVO;
import com.cmc.cloud.cmclink.doc.vo.sovo.sovslvoyvo.SoVslvoyUpdateReqVO;
import com.cmc.cloud.cmclink.ibsmgmt.api.mgmt.dto.TopAgentSettingRespDTO;
import com.cmc.cloud.cmclink.svl.api.base.req.PolPodReqDTO;
import com.cmes.framework.biz.advice.annotations.UseResponsePropertyAdvice;
import com.cmes.framework.common.pojo.CommonResult;
import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.security.core.util.SecurityFrameworkUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;


/**
 * 订舱前端接口Controller
 *
 * @author chenzheng
 */
@Tag(name = "管理后台 - 订舱")
@RestController
@Validated
@RequestMapping(UrlConstants.APPLICATION_URL + "/so")
public class SoController {
    @Resource
    private BizSoService bizSoService;

    @Resource
    private IbsMgmtService ibsMgmtService;
    @Resource
    private SoQueryServiceImpl soQueryService;


    @Operation(summary = "创建订舱")
    @PostMapping("/create")
    @PreAuthorize("@ss.hasPermission('doc:shipment:create')")
    public CommonResult<Long> createSo(@Valid @RequestBody SoCreateAndUpdateReqVo createReqVO) {
        return CommonResult.success(bizSoService.createOrUpdateSo(createReqVO, false, String.valueOf(SecurityFrameworkUtils.getLoginUserId())));
    }

    @Operation(summary = "更新订舱")
    @PostMapping("/update")
    @PreAuthorize("@ss.hasPermission('doc:shipment:edit')")
    public CommonResult<Long> updateSo(@Valid @RequestBody SoCreateAndUpdateReqVo updateReqVO) {
        return CommonResult.success(bizSoService.createOrUpdateSo(updateReqVO, true, String.valueOf(SecurityFrameworkUtils.getLoginUserId())));
    }

    @Operation(summary = "创建订舱并提交")
    @PostMapping("/createAndSubmit")
    @PreAuthorize("@ss.hasPermission('doc:shipment:create')")
    public CommonResult<Long> createAndSubmit(@Valid @RequestBody SoCreateAndUpdateReqVo createReqVO) {
        return CommonResult.success(bizSoService.createAndSubmit(createReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId())));
    }

    @Operation(summary = "删除订舱")
    @PostMapping("/delete/{id}")
    @Parameter(name = "id", description = "id", required = true)
    @PreAuthorize("@ss.hasPermission('doc:shipment:batchDeleteDraft')")
    public CommonResult<Void> deleteSo(@PathVariable("id") Long id) {
        bizSoService.batchDeleteDraft(ListUtil.of(id), String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "获得订舱详细")
    @GetMapping("/get/{id}")
    @Parameter(name = "id", description = "id", required = true, example = "123")
    @UseResponsePropertyAdvice
    @PreAuthorize("@ss.hasPermission('doc:shipment:preview')")
    public CommonResult<SoDetailRespVO> getSo(@PathVariable("id") Long id) {
        SoDetailRespVO detail = bizSoService.getDetail(id);
        return CommonResult.success(detail);
    }

    @Operation(summary = "获得订舱详情多个列表")
    @PostMapping("/getSoDetailList")
    @PreAuthorize("@ss.hasPermission('doc:shipment:preview')")
    public CommonResult<List<SoDetailRespVO>> getSoDetailList(@RequestBody List<Long> ids) {
        return CommonResult.success(bizSoService.getDetailList(ids));
    }

    @Operation(summary = "订舱号/提单号获得订舱详细")
    @PostMapping("/getByBookingNoOrBlNo")
    public CommonResult<SoDetailRespVO> getByBookingNoOrBlNo(@RequestBody SoQueryReqVO queryReq) {
        return CommonResult.success(bizSoService.getByBookingNoOrBlNo(queryReq));
    }

    @Operation(summary = "获得订舱分页")
    @PostMapping("/page")
    @UseResponsePropertyAdvice
    @PreAuthorize("@ss.hasPermission('doc:shipment:search')")
    public CommonResult<PageResult<SoRespVO>> getSoPage(@RequestBody SoPageReqVO pageVO) {
        pageVO.setNoQueryWebDraft(true);
        return CommonResult.success(bizSoService.getSoPage(pageVO));
    }

    @Operation(summary = "获得订舱列表")
    @PostMapping("/queryList")
    @UseResponsePropertyAdvice
    public CommonResult<List<SoRespVO>> queryList(@Valid @RequestBody SoListReqVO reqVO) {
        return CommonResult.success(bizSoService.queryList(reqVO));
    }

    @Operation(summary = "订舱草稿批量提交")
    @PostMapping("/batchSubmitDraft")
    @PreAuthorize("@ss.hasPermission('doc:shipment:batchSubmitDraft')")
    public CommonResult batchSubmitDraft(@RequestBody List<Long> ids) {
        bizSoService.batchSubmitDraft(ids, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱批量返回草稿")
    @PostMapping("/batchReturnToDraft")
    @PreAuthorize("@ss.hasPermission('doc:shipment:batchReturnToDraft')")
    public CommonResult batchReturnToDraft(@RequestBody List<Long> ids) {
        bizSoService.batchReturnToDraft(ids, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱批量取消")
    @PostMapping("/batchCancelBooking")
    @PreAuthorize("@ss.hasPermission('doc:shipment:batchCancelBooking')")
    public CommonResult batchCancelBooking(@RequestBody List<Long> ids) {
        return bizSoService.batchCancelBooking(ids, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
    }

    @Operation(summary = "订舱草稿批量删除")
    @PostMapping("/batchDeleteDraft")
    @PreAuthorize("@ss.hasPermission('doc:shipment:batchDeleteDraft')")
    public CommonResult batchDeleteDraft(@RequestBody List<Long> ids) {
        bizSoService.batchDeleteDraft(ids, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱草稿批量复制")
    @PostMapping("/batchCopy")
    @PreAuthorize("@ss.hasPermission('doc:shipment:batchCopy')")
    public CommonResult batchCopy(@RequestBody List<Long> ids) {
        bizSoService.batchCopy(ids, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱详情复制")
    @GetMapping("/copyDetail/{id}")
    @Parameter(name = "id", description = "id", required = true, example = "123")
    @PreAuthorize("@ss.hasPermission('doc:shipment:copyDetail')")
    public CommonResult<SoCopyDetailRespVo> copyDetail(@PathVariable("id") Long id) {
        return CommonResult.success(bizSoService.copyDetail(id, String.valueOf(SecurityFrameworkUtils.getLoginUserId()), false));
    }

    @Operation(summary = "批量修改订舱的船名航次")
    @PostMapping("/batchChangeBkgVessel")
    @PreAuthorize("@ss.hasPermission('doc:soContent:batchChangeVessel')")
    public CommonResult batchChangeBkgVessel(@Valid @RequestBody SoVslvoyUpdateReqVO updateReqVO) {
        bizSoService.batchChangeBkgVessel(updateReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱批量审核内容")
    @PostMapping("/batchApproveContent")
    @PreAuthorize("@ss.hasPermission('doc:soContent:batchApproveContent')")
    public CommonResult batchApproveContent(@RequestBody List<Long> ids) {
        bizSoService.changeSoContentStatus(ids, null, null, SoContentStatusEnum.APPROVED.getValue(), String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱批量审核内容拒绝")
    @PostMapping("/batchRejectContent")
    @PreAuthorize("@ss.hasPermission('doc:soContent:batchRejectContent')")
    public CommonResult batchRejectContent(@RequestBody SoContentRejectReqVO rejectReqVO) {
        bizSoService.changeSoContentStatus(rejectReqVO.getSoIdList(), rejectReqVO.getReasonType(), rejectReqVO.getDescCn(), SoContentStatusEnum.REJECTED.getValue(), String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱待补充材料")
    @PostMapping("/awaitingMaterialUploaded")
    public CommonResult awaitingMaterialUploaded(@RequestBody SoContentRejectReqVO rejectReqVO) {
        bizSoService.awaitingMaterialUploaded(rejectReqVO.getSoIdList(), rejectReqVO.getReasonType(), rejectReqVO.getDescCn(), String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱审核通过打印")
    @PostMapping("/bookingComfirmPrint/{soId}")
    @PreAuthorize("@ss.hasPermission('doc:soContent:bookingComfirmPrint')")
    public void bookingComfirmPrint(HttpServletResponse response, @PathVariable("soId") Long soId) {
        bizSoService.bookingComfirmPrint(response, soId);
    }

    @Operation(summary = "订舱审核通过打印")
    @GetMapping("/bookingComfirmPrintGet/{soId}")
    @PreAuthorize("@ss.hasPermission('doc:soContent:bookingComfirmPrint')")
    public void bookingComfirmPrintGet(HttpServletResponse response, @PathVariable("soId") Long soId) {
        bizSoService.bookingComfirmPrint(response, soId);
    }

    @Operation(summary = "订舱BCR内容检查")
    @GetMapping("/checkSoBcr/{soId}")
    @Parameter(name = "soId", description = "soId", required = true, example = "123")
    public CommonResult<SoDetailRespVO> checkSoBcr(@PathVariable("soId") Long soId) {
        SoDetailRespVO result = bizSoService.checkSoBcr(soId);
        return CommonResult.success(result);
    }

    @Operation(summary = "订舱已确认修改申请检查")
    @GetMapping("/updateConfirmedSoAmendCheck/{soId}")
    public CommonResult<Long> updateConfirmedSoAmendCheck(@PathVariable("soId") Long soId) {
        bizSoService.updateConfirmedSoAmendCheck(soId, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱已确认修改内容申请")
    @PostMapping("/updateConfirmedSoAmend")
    @PreAuthorize("@ss.hasPermission('doc:shipment:changeApply')")
    public CommonResult<Long> updateConfirmedSoAmend(@Valid @RequestBody SoCreateAndUpdateReqVo updateReqVO) {
        return CommonResult.success(bizSoService.updateConfirmedSoAmend(updateReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId())));
    }

    @Operation(summary = "订舱已确认改船名航次申请")
    @PostMapping("/updateConfirmedSoAmendVessel")
    @PreAuthorize("@ss.hasPermission('doc:shipment:codApply')")
    @LogSetting(reqParamLimit = 10000, resParamLimit = 10000)
    public CommonResult<Long> updateConfirmedSoAmendVessel(@Valid @RequestBody SoCreateAndUpdateReqVo updateReqVO) {
        return CommonResult.success(bizSoService.updateConfirmedSoAmendVessel(updateReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId())));
    }


    @Operation(summary = "订舱对比查看")
    @GetMapping("/getAmendApplyDetail/{amendApplyId}")
    @PreAuthorize("@ss.hasPermission('doc:soChange:preview')")
    public CommonResult<SoDetailCompareRespVo> getAmendApplyDetail(@PathVariable("amendApplyId") Long amendApplyId) {
        return CommonResult.success(bizSoService.getAmendApplyDetail(amendApplyId));
    }

    @Operation(summary = "修改审批取消")
    @PostMapping("/amendCancel/{amendApplyId}")
    public CommonResult amendCancel(@PathVariable("amendApplyId") Long amendApplyId) {
        bizSoService.amendCancel(amendApplyId, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱已确认修改审批通过")
    @PostMapping("/amendConfirmed/{amendApplyId}")
    public CommonResult amendConfirmed(@PathVariable("amendApplyId") Long amendApplyId) {
        SoAmendApplyUpdateReqVO updateReqVO = new SoAmendApplyUpdateReqVO();
        updateReqVO.setId(amendApplyId);
        updateReqVO.setSoAmendStatus(ContentChangeStatusEnum.BOOKING_CHANGE_CONFIRMED.getValue());
        bizSoService.updateConfirmedSoAudit(updateReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱已确认修改审批拒绝")
    @PostMapping("/amendRejected")
    public CommonResult amendRejected(@Valid @RequestBody SoAmendApplyUpdateReqVO updateReqVO) {
        updateReqVO.setSoAmendStatus(ContentChangeStatusEnum.BOOKING_CHANGE_REJECTED.getValue());
        bizSoService.updateConfirmedSoAudit(updateReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱取消申请")
    @PostMapping("/cancelSoAmend")
    public CommonResult<Void> cancelSoAmend(@Valid @RequestBody SoCancelReqVo cancelReqVO) {
        bizSoService.cancelSoAmend(cancelReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱已确认取消申请审批通过")
    @PostMapping("/cancelSoAmendConfirmed/{amendApplyId}")
    public CommonResult cancelSoAmendConfirmed(@PathVariable("amendApplyId") Long amendApplyId) {
        SoAmendApplyUpdateReqVO updateReqVO = new SoAmendApplyUpdateReqVO();
        updateReqVO.setId(amendApplyId);
        updateReqVO.setSoAmendStatus(ContentChangeStatusEnum.BOOKING_CANCEL_CONFIRMED.getValue());
        bizSoService.cancelSoAudit(updateReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "订舱已确认取消申请审批拒绝")
    @PostMapping("/cancelSoAmendRejected")
    public CommonResult cancelSoAmendRejected(@Valid @RequestBody SoAmendApplyUpdateReqVO updateReqVO) {
        updateReqVO.setSoAmendStatus(ContentChangeStatusEnum.BOOKING_CANCEL_REJECTED.getValue());
        bizSoService.cancelSoAudit(updateReqVO, String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        return CommonResult.success();
    }

    @Operation(summary = "修改审批订舱分页")
    @PostMapping("/amendApplyPage")
    @UseResponsePropertyAdvice
    @PreAuthorize("@ss.hasPermission('doc:soChange:search')")
    public CommonResult<PageResult<SoRespVO>> amendApplyPage(@RequestBody SoPageReqVO pageVO) {
        return CommonResult.success(bizSoService.getSoPageAmend(pageVO));
    }


    @Operation(summary = "查找时间范围内的装货港和卸货港")
    @PostMapping("/getLineScheduleByPolPod")
    @UseResponsePropertyAdvice
    public CommonResult<List<SoVslvoyScheduleVO>> getLineScheduleByPolPod(@RequestBody PolPodReqDTO polPodReq) {
        return CommonResult.success(bizSoService.getLineScheduleByPolPod(polPodReq));
    }

    @Operation(summary = "COD校验接口")
    @PostMapping("/checkCodTime")
    @PreAuthorize("@ss.hasPermission('doc:shipment:codApply')")
    public CommonResult<Boolean> checkCodTime(@Valid @RequestBody CodCheckReqVO reqVO) {
        boolean result = bizSoService.checkCodTime(reqVO);
        return CommonResult.success(result);
    }


    @Operation(summary = "根据cmcCode polCode 获取一级代理人")
    @PostMapping("/getTopAgentByCsmCodeAndPol")
    public CommonResult<TopAgentSettingRespDTO> getTopAgentByCsmCodeAndPol(@RequestBody SoTopAgentReqVO req) {
        return CommonResult.success(ibsMgmtService.getTopAgentByCsmCodeAndPol(req.getCsmCode(), req.getPolCode()));
    }


    @Operation(summary = "订舱监控报表")
    @PostMapping("/getSoBasCount")
    public CommonResult<SoBsaALlCountVO> getSoBasCount(@RequestBody SoBsaCountReqVO req) {
        return CommonResult.success(soQueryService.querySoBsaCustomerCount(req));
    }

}
